/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.factory.web.service;

import com.factory.web.json.Stats;
import com.factory.web.dto.UserDTO;
import com.factory.web.dto.UserTaskDTO;
import com.factory.web.json.Plan;
import com.factory.web.json.Problem;
import com.factory.web.json.UserTasksWrapper;
import com.factory.web.json.UsersWrapper;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ws.rs.core.MediaType;
import org.springframework.stereotype.Service;

/**
 *
 * @author milos
 */
@Service("factoryService")
public class FactoryService implements FactoryServiceInterface {

    static final Logger LOG = Logger.getLogger(FactoryService.class.getName());
    private Problem problem;
    private Client client;
    private String userId;
    private String passwordHash;
    private String inputId;
    private final static String url = "http://localhost:8084/algorithms-factory-server/webresources/factory";

    public void upload(InputStream fileInStream) {
        client = new Client();
        if (fileInStream != null) {

            BufferedReader br = new BufferedReader(new InputStreamReader(fileInStream));
            try {
                String line = br.readLine();
                while (line != null) {
                    problem.addLine(line);
                    line = br.readLine();
                }
            } catch (IOException ex) {
                //TODO handle exception
            }
        }
        WebResource fileResource = client.resource(url).path("/fileUpload/");

        problem.setUserId(userId);
        this.inputId = fileResource
                .type(MediaType.APPLICATION_JSON)
                .header("Name", userId)
                .header("PasswordHash", passwordHash)
                .post(String.class, problem);
    }

    public InputStream getResultFile(String inputId) {
        client = new Client();
        WebResource resource = client.resource(url + "/getResultFile/").path(inputId);

        ClientResponse response = resource
                .header("Name", userId)
                .header("PasswordHash", passwordHash)
                .accept(MediaType.APPLICATION_OCTET_STREAM)
                .type(MediaType.APPLICATION_OCTET_STREAM)
                .get(ClientResponse.class);

        return response.getEntityInputStream();
    }

    public boolean runFactory(Plan plan) {
        client = new Client();
        WebResource resource = client.resource(url);
        resource
                .path("runFactory").type(javax.ws.rs.core.MediaType.APPLICATION_JSON)
                .header("Name", userId)
                .header("PasswordHash", passwordHash)
                .post(ClientResponse.class, plan);

        return false;
    }

    public List<UserTaskDTO> getUserTasks() {
        client = new Client();
        WebResource resource = client.resource(url + "/getUserTasks/").path(userId);
        UserTasksWrapper response = resource
                .header("Name", userId)
                .header("PasswordHash", passwordHash)
                .accept(MediaType.APPLICATION_JSON_TYPE)
                .type(MediaType.TEXT_PLAIN_TYPE)
                .get(UserTasksWrapper.class);
        return response.getUserTasks();
    }

    public void setProblem(Problem problem) {
        this.problem = problem;
    }

    public Problem getProblem() {
        return this.problem;
    }

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public String getInputId() {
        return inputId;
    }

    public void setInputId(String inputId) {
        this.inputId = inputId;
    }

    public boolean register(UserDTO userDTO) {
        userDTO.setIsAdmin(false);
        client = new Client();
        WebResource resource = client.resource(url);
        ClientResponse response = resource.path("register").type(javax.ws.rs.core.MediaType.APPLICATION_JSON)
                .header("Name", userId)
                .header("PasswordHash", passwordHash)
                .post(ClientResponse.class, userDTO);
        if (response.getStatus() == 304 || response.getStatus() == 500) {
            return false;
        } else {
            return true;
        }
    }

    public List<UserDTO> getAllUsers() {
        client = new Client();
        WebResource resource = client.resource(url + "/getAllUsers/");

        UsersWrapper response = resource
                .header("Name", userId)
                .header("PasswordHash", passwordHash)
                .accept(MediaType.APPLICATION_JSON_TYPE)
                .type(MediaType.TEXT_PLAIN_TYPE)
                .get(UsersWrapper.class);

        return response.getUsersList();
    }

    public Stats getStats() {
        client = new Client();
        WebResource resource = client.resource(url + "/getStats/");

        Stats response = resource
                .header("Name", userId)
                .header("PasswordHash", passwordHash)
                .accept(MediaType.APPLICATION_JSON_TYPE)
                .type(MediaType.TEXT_PLAIN_TYPE)
                .get(Stats.class);
        return response;
    }

    public void updateUser(UserDTO userDTO) {
        client = new Client();
        WebResource resource = client.resource(url);
        resource
                .path("updateUser").type(javax.ws.rs.core.MediaType.APPLICATION_JSON)
                .header("Name", userId)
                .header("PasswordHash", passwordHash)
                .post(ClientResponse.class, userDTO);
    }

    public String authorize(UserDTO userDTO) {
        client = new Client();
        WebResource resource = client.resource(url);
        String response = resource.path("authorize").type(javax.ws.rs.core.MediaType.APPLICATION_JSON)
                .post(String.class, userDTO);

        return response;
    }

    public String getPasswordHash() {
        return passwordHash;
    }

    public void setPasswordHash(String passwordHash) {
        this.passwordHash = passwordHash;
    }
}
